package org.ling.xuan.gutter;


import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiExpressionList;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.ling.xuan.util.Icons;

import java.util.Collection;


public class FileConfigGutterIconProvider extends RelatedItemLineMarkerProvider {


    protected void collectNavigationMarkers(@NotNull PsiElement element,
                                            @NotNull Collection<? super RelatedItemLineMarkerInfo<?>> result) {
        if (match(element)) {
            PsiMethodCallExpression pse = (PsiMethodCallExpression) element;
            NavigationGutterIconBuilder<PsiElement> builder =
                    NavigationGutterIconBuilder.create(Icons.FILE_CONFIG)
                            .setTargets(getSpringPsiClass(element))
                            .setTooltipText("file config param ...");
            result.add(builder.createLineMarkerInfo(pse));
        }
    }

    private boolean match(PsiElement element) {
        if (element instanceof PsiMethodCallExpression) {
            PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) element;
            PsiExpressionList argumentList = methodCallExpression.getArgumentList();
            if (!methodCallExpression.getArgumentList().isEmpty()) {
                boolean containsClassArgs = false;
                String cl = "java.lang.Class";
                for (PsiType type : argumentList.getExpressionTypes()) {
                    if (type!=null&&type.getCanonicalText().contains(cl)) {
                        containsClassArgs = true;
                        break;
                    }
                }
                if (!containsClassArgs) {
                    //参数为空 或者 中有包含 ***.class才去判断所调用的方法是否有Spring服务类
                    return false;
                }
            }
            PsiMethod method = methodCallExpression.resolveMethod();
            if (method != null) {
                String s = method.getText();
                boolean matched = s.contains("SpringContextFactory") && s.contains("getApplicationContext()") && s.contains("getBean");
                if (matched) {
                   if(method.getReturnType()!=null){
                       PsiType psiType = method.getReturnType();
                       return psiType.getCanonicalText().contains("ISysConfig");
                   }
                }
            }
        }
        return false;
    }

    public PsiElement getSpringPsiClass(@NotNull PsiElement element) {
        if (element instanceof PsiMethodCallExpression) {
            PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) element;
            PsiMethod method = methodCallExpression.resolveMethod();
            if (method != null) {
                PsiExpressionList argumentList = methodCallExpression.getArgumentList();
                if (!argumentList.isEmpty()) {
                    for (PsiExpression ele : argumentList.getExpressions()) {
                        if (ele.getText().endsWith(".class")) {
                            if(ele.getNavigationElement()!=null){
                                return ele.getNavigationElement();
                            }
                            return ele;
                        }
                    }
                    return argumentList.getExpressions()[0];
                } else {
                    return method.getReturnTypeElement();
                }
            }
        }
        return null;
    }

}
